package saolei;

import javax.swing.*;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.*;
import java.util.*;
import javax.swing.ImageIcon;

public class GameGUI extends JFrame {
    private int is_Victory;
    private JLabel flagslabel = new JLabel();
    private JLabel timelabel = new JLabel();
    private long time;

    class MineFieldGUI extends JPanel {
        // 地雷区的GUI部分，将雷区设置在一个JPanel中
        private int mineNum;
        private int xNum;
        private int yNum;
        private int flagNum;
        private MineField mf;
        private ArrayList<ButtonCoordinate> buttons = new ArrayList<ButtonCoordinate>();

        public MineFieldGUI(int mineNum, int xNum, int yNum, MineField mf) {
            this.mineNum = mineNum;
            this.xNum = xNum;
            this.yNum = yNum;
            this.flagNum = 0;
            this.mf = mf;
        }

        public void init() {
            // 生成雷区
            // 必须设置其Layout为null，不然JButton的setBounds不起作用
            is_Victory = -1;
            this.setLayout(null);
            this.setBounds(5, 115, yNum * 51 + 5, xNum * 51 + 5);
            for (int i = 1; i <= this.xNum; i++) {
                for (int j = 1; j <= this.yNum; j++) {
                    final ButtonCoordinate current = new ButtonCoordinate(i, j);
                    this.add(current);
                    current.setBounds((j - 1) * 50 + j, (i - 1) * 50 + i, 50, 50);
                    current.addMouseListener(new MouseAdapter() {
                        public void mouseClicked(MouseEvent e) {
                            // 左键点击
                            if (e.getButton() == MouseEvent.BUTTON1) {
                                is_Victory = current.leftClick(mf, yNum, buttons);
                                if (is_Victory != -1)
                                    // 游戏结束，显示所有的格子
                                    gameOver();
                            }
                            // 右键点击
                            if (e.getButton() == MouseEvent.BUTTON3) {
                                flagNum = current.rightClick(mf, yNum, flagNum, mineNum);
                                flagslabel.setText("剩余炸弹数:" + (mineNum - flagNum));
                            }
                        }
                    });
                    buttons.add(current);
                }
            }
            this.revalidate();
            this.repaint();
            return;
        }

        private void gameOver() {
            ImageIcon icon = new ImageIcon("././jpg/mine.jpg");
            Image temp1 = icon.getImage().getScaledInstance(this.getWidth(),
                    this.getHeight(), icon.getImage().SCALE_DEFAULT);
            icon = new ImageIcon(temp1);
            for (int index = 0; index < this.mf.getCoordinates().size(); index++) {
                Coordinate ccurrent = this.mf.getCoordinates().get(index);
                ButtonCoordinate bcurrent = this.buttons.get(index);
                if (ccurrent.getNum() > 0)
                    bcurrent.setText(ccurrent.getNum() + "");
                if (ccurrent.getNum() == -1 && ccurrent.getIsMine() == 0)
                   bcurrent.setIcon(icon);
                bcurrent.setEnabled(false);
            }
            return;
        }
    }

    private class CountingThread extends Thread {
        private long programStart;
        private boolean is_end = false;

        private CountingThread(long currenttime) {
            setDaemon(true);
            this.programStart = currenttime;
        }

        @Override
        public void run() {
            while (!is_end) {
                if (is_Victory == -1) {
                    long elapsed = System.currentTimeMillis() - programStart;
                    timelabel.setText("已用时间：" + format(elapsed));
                } else {
                    time = System.currentTimeMillis() - programStart;
                    timelabel.setText("已用时间：" + format(time));
                    is_end = true;
                }
                try {
                    // 100ms刷新一次
                    sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }

        private String format(long elapsed) {
            // 将毫秒数格式化
            int hour, minute, second;
            elapsed = elapsed / 1000;
            second = (int) (elapsed % 60);
            elapsed = elapsed / 60;
            minute = (int) (elapsed % 60);
            elapsed = elapsed / 60;
            hour = (int) (elapsed % 60);
            return String.format("%02d:%02d:%02d", hour, minute, second);
        }
    }

    class TipsGUI extends JPanel {
        // 显示玩家的剩余炸弹数，时间等等信息
        public void init(int ynum) {
            this.setLayout(null);
            this.setBounds(10, 10, ynum * 50, 100);
            Font font = new Font("宋体", Font.ITALIC + Font.BOLD, 20);
            this.add(flagslabel);
            flagslabel.setBounds(5, 5, ynum * 50, 45);
            flagslabel.setFont(font);
            this.add(timelabel);
            timelabel.setBounds(5, 55, ynum * 50, 45);
            timelabel.setFont(font);
            return;
        }
    }

    public void CreateGame(int mineNum, int xNum, int yNum, MineField mf) {
        MyLogger.logger.info("初始化扫雷图形页面");
        JFrame frame = new JFrame("MineField");
        frame.setSize(yNum * 51 + 30, xNum * 51 + 170);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setLayout(null);
        MineFieldGUI mfg = new MineFieldGUI(mineNum, xNum, yNum, mf);
        mfg.init();
        frame.add(mfg);
        TipsGUI tg = new TipsGUI();
        tg.init(yNum);
        frame.add(tg);
        frame.revalidate();
        frame.repaint();
        flagslabel.setText("剩余炸弹数:" + mineNum);
        CountingThread timer = new CountingThread(System.currentTimeMillis());
        timer.start();
    }

    public int getIs_Victory() {
        return is_Victory;
    }

    public long getTime() {
        return time;
    }
}

class ButtonCoordinate extends JButton {
    // 记录坐标的按钮，不能用xy表示，xy已经用来表示按钮的位置
    private int i;
    private int j;
    private int isMine;// 与Coordinate中的isMine相同

    public ButtonCoordinate(int i, int j) {
        this.i = i;
        this.j = j;
        this.isMine = 0;
    }

    public int getI() {
        return this.i;
    }

    public int getJ() {
        return this.j;
    }

    public int getIsMine() {
        return isMine;
    }

    public void setIsMine(int isMine) {
        this.isMine = isMine;
    }

    public int leftClick(MineField mf, int yNum, ArrayList<ButtonCoordinate> buttons) {
        // 左键点击，并判断游戏输赢I
        // 0为输，1为赢，-1为尚未结束J
        int index = (this.getI() - 1) * yNum + this.getJ() - 1;
        if (mf.getCoordinates().get(index).getIsMine() == 1)
            return mf.isVctory();
        if (mf.getCoordinates().get(index).getNum() == -1) {// 是炸弹
            return 0;
        } else if (mf.getCoordinates().get(index).getNum() == 0) {// 点击到空白区域
            ArrayList<Integer> resualt = mf.checkGrid(index);
            for (int i : resualt) {
                if (mf.getCoordinates().get(i).getNum() > 0)
                    buttons.get(i).setText("" + mf.getCoordinates().get(i).getNum());
                buttons.get(i).setEnabled(false);
            }
        } else {// 点击到非空白区域
            this.setText("" + mf.getCoordinates().get(index).getNum());
            buttons.get(index).setEnabled(false);
        }
        return -1;
    }

    public int rightClick(MineField mf, int yNum, int flagNum, int mineNum) {
        // 右键点击
        int index = (this.getI() - 1) * yNum + this.getJ() - 1;
        // 根据路径创建图标
        ImageIcon icon = new ImageIcon("././jpg/flag.jpg");
        // 新建图片，大小调制成和按钮大小一样大
        Image temp1 = icon.getImage().getScaledInstance(this.getWidth(),
                this.getHeight(), icon.getImage().SCALE_DEFAULT);
        // 将图片另引用为图标
        icon = new ImageIcon(temp1);
        if (mf.getCoordinates().get(index).getIsMine() == 1) { // 取消插旗
            flagNum--;
            mf.getCoordinates().get(index).setIsMine(0);
            this.setIsMine(0);
            this.setText("");
            this.setIcon(null);
            return flagNum;
        }
        if (flagNum < mineNum) { // 插旗
            flagNum++;
            mf.getCoordinates().get(index).setIsMine(1);
            this.setIsMine(1);
            // 将图标加载到按钮之上
            this.setIcon(icon);
        } else { // 提示不能插旗
            JOptionPane.showMessageDialog(null, "插旗数已达上限");
        }
        return flagNum;
    }
}
